#pragma once
#include <string>
#include "../CryptoModule/IAsymmetric.h"
#include "../CryptoModule/ICrypto.h"
#include "../CryptoModule/Base64.h"
#include "../CryptoModule/HexString.h"
#include "../CryptoModule/Sha256.h"

class EnclaveVault
{
public:
    EnclaveVault(const std::string &id);
    virtual ~EnclaveVault();

    int initEnclaveVault();

    const char* id() const { return id_.c_str(); }

    int encrypt(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

	int encrypt_size(int buf_len);

    int decrypt(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

    int public_key_encrypt(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

    int private_key_decrypt(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

    int private_key_encrypt(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

    int public_key_decrypt(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

	int sign(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

	int sha256(const char *in_buf, int in_buf_len, char *out_buf, int out_buf_size);

protected:
   
    void initRsaSecurity();

    int initDesSecurity();

    int readFile(std::string &out, const std::string & file_name);
    int writeFile(std::string &out, const std::string & file_name);

    inline const std::string pub_key_full_name() const { return user_data_dir_ + "/" + id_ + "/" + pub_key_name_; }

    inline const std::string pri_key_full_name() const { return user_data_dir_ + "/" + id_ + "/" + pri_key_name_; }

    inline const std::string crypto_key_full_name() const { return user_data_dir_ + "/" + id_ + "/" + crypto_key_name_; }

public:
    const std::string id_;

    std::string user_data_dir_ = "UserData";

    int asymmetric_size_ = 256;
    std::string pub_key_name_ = "public_key.pem";
    std::string pri_key_name_ = "private_key.pem";
    IAsymmetric *asymmetric_ = nullptr;

    int crypto_key_length_ = 16;
    std::string crypto_key_name_ = "crypto.key";
    ICrypto *crypto_ = nullptr;

    Base64 base64_ = Base64();

    HexString hex_string_ = HexString();

    Sha256 sha256_ = Sha256();
};

